using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
namespace Microsoft.Phone.Controls
{
	[TemplatePart(Name = "FirstContentPresenter", Type = typeof(ContentPresenter)), TemplatePart(Name = "SecondContentPresenter", Type = typeof(ContentPresenter))]
	public class TransitionFrame : PhoneApplicationFrame
	{
		private const string FirstTemplatePartName = "FirstContentPresenter";
		private const string SecondTemplatePartName = "SecondContentPresenter";
		internal static readonly CacheMode BitmapCacheMode = new BitmapCache();
		private ContentPresenter _firstContentPresenter;
		private ContentPresenter _secondContentPresenter;
		private ContentPresenter _newContentPresenter;
		private ContentPresenter _oldContentPresenter;
		private bool _isForwardNavigation;
		private bool _useFirstAsNew;
		private bool _readyToTransitionToNewContent;
		private bool _contentReady;
		private bool _performingExitTransition;
		private ITransition _storedNewTransition;
		private NavigationInTransition _storedNavigationInTransition;
		private ITransition _storedOldTransition;
		private NavigationOutTransition _storedNavigationOutTransition;
		public TransitionFrame()
		{
			base.set_DefaultStyleKey(typeof(TransitionFrame));
			base.add_Navigating(new NavigatingCancelEventHandler(this.OnNavigating));
			base.add_BackKeyPress(new EventHandler<CancelEventArgs>(this.OnBackKeyPress));
		}
		private void FlipPresenters()
		{
			this._newContentPresenter = (this._useFirstAsNew ? this._firstContentPresenter : this._secondContentPresenter);
			this._oldContentPresenter = (this._useFirstAsNew ? this._secondContentPresenter : this._firstContentPresenter);
			this._useFirstAsNew = !this._useFirstAsNew;
		}
		private void OnNavigating(object sender, NavigatingCancelEventArgs e)
		{
			this._isForwardNavigation = (e.get_NavigationMode() != 1);
			UIElement uIElement = base.get_Content() as UIElement;
			if (uIElement == null)
			{
				return;
			}
			this.FlipPresenters();
			TransitionElement transitionElement = null;
			ITransition transition = null;
			NavigationOutTransition navigationOutTransition = TransitionService.GetNavigationOutTransition(uIElement);
			if (navigationOutTransition != null)
			{
				transitionElement = (this._isForwardNavigation ? navigationOutTransition.Forward : navigationOutTransition.Backward);
			}
			if (transitionElement != null)
			{
				transition = transitionElement.GetTransition(uIElement);
			}
			if (transition != null)
			{
				TransitionFrame.EnsureStoppedTransition(transition);
				this._storedNavigationOutTransition = navigationOutTransition;
				this._storedOldTransition = transition;
				transition.Completed += new EventHandler(this.OnExitTransitionCompleted);
				this._performingExitTransition = true;
				TransitionFrame.PerformTransition(navigationOutTransition, this._oldContentPresenter, transition);
				TransitionFrame.PrepareContentPresenterForCompositor(this._oldContentPresenter, true);
				return;
			}
			this._readyToTransitionToNewContent = true;
		}
		private void OnExitTransitionCompleted(object sender, EventArgs e)
		{
			this._readyToTransitionToNewContent = true;
			this._performingExitTransition = false;
			TransitionFrame.CompleteTransition(this._storedNavigationOutTransition, null, this._storedOldTransition);
			this._storedNavigationOutTransition = null;
			this._storedOldTransition = null;
			if (this._contentReady)
			{
				ITransition storedNewTransition = this._storedNewTransition;
				NavigationInTransition storedNavigationInTransition = this._storedNavigationInTransition;
				this._storedNewTransition = null;
				this._storedNavigationInTransition = null;
				this.TransitionNewContent(storedNewTransition, storedNavigationInTransition);
			}
		}
		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
			this._firstContentPresenter = (base.GetTemplateChild("FirstContentPresenter") as ContentPresenter);
			this._secondContentPresenter = (base.GetTemplateChild("SecondContentPresenter") as ContentPresenter);
			this._newContentPresenter = this._secondContentPresenter;
			this._oldContentPresenter = this._firstContentPresenter;
			this._useFirstAsNew = true;
			this._readyToTransitionToNewContent = true;
			if (base.get_Content() != null)
			{
				this.OnContentChanged(null, base.get_Content());
			}
		}
		protected override void OnContentChanged(object oldContent, object newContent)
		{
			base.OnContentChanged(oldContent, newContent);
			this._contentReady = true;
			UIElement content = oldContent as UIElement;
			UIElement uIElement = newContent as UIElement;
			if (this._firstContentPresenter == null || this._secondContentPresenter == null || uIElement == null)
			{
				return;
			}
			NavigationInTransition navigationInTransition = null;
			ITransition transition = null;
			if (uIElement != null)
			{
				navigationInTransition = TransitionService.GetNavigationInTransition(uIElement);
				TransitionElement transitionElement = null;
				if (navigationInTransition != null)
				{
					transitionElement = (this._isForwardNavigation ? navigationInTransition.Forward : navigationInTransition.Backward);
				}
				if (transitionElement != null)
				{
					uIElement.UpdateLayout();
					transition = transitionElement.GetTransition(uIElement);
					TransitionFrame.PrepareContentPresenterForCompositor(this._newContentPresenter, true);
				}
			}
			this._newContentPresenter.set_Opacity(0.0);
			this._newContentPresenter.set_Visibility(0);
			this._newContentPresenter.set_Content(uIElement);
			this._oldContentPresenter.set_Opacity(1.0);
			this._oldContentPresenter.set_Visibility(0);
			this._oldContentPresenter.set_Content(content);
			if (this._readyToTransitionToNewContent)
			{
				this.TransitionNewContent(transition, navigationInTransition);
				return;
			}
			this._storedNewTransition = transition;
			this._storedNavigationInTransition = navigationInTransition;
		}
		private void OnBackKeyPress(object sender, CancelEventArgs e)
		{
			if (this._performingExitTransition)
			{
				UIElement uIElement = base.get_Content() as UIElement;
				if (uIElement == null)
				{
					return;
				}
				TransitionElement transitionElement = null;
				ITransition transition = null;
				NavigationOutTransition navigationOutTransition = TransitionService.GetNavigationOutTransition(uIElement);
				if (navigationOutTransition != null)
				{
					transitionElement = (this._isForwardNavigation ? navigationOutTransition.Forward : navigationOutTransition.Backward);
				}
				if (transitionElement != null)
				{
					transition = transitionElement.GetTransition(uIElement);
				}
				if (transition != null)
				{
					TransitionFrame.CompleteTransition(this._storedNavigationOutTransition, null, this._storedOldTransition);
					this.TransitionNewContent(transition, null);
				}
			}
		}
		private void TransitionNewContent(ITransition newTransition, NavigationInTransition navigationInTransition)
		{
			if (this._oldContentPresenter != null)
			{
				this._oldContentPresenter.set_Visibility(1);
				this._oldContentPresenter.set_Content(null);
			}
			if (newTransition == null)
			{
				TransitionFrame.RestoreContentPresenterInteractivity(this._newContentPresenter);
				return;
			}
			TransitionFrame.EnsureStoppedTransition(newTransition);
			newTransition.Completed += delegate(object sender, EventArgs e)
			{
				TransitionFrame.CompleteTransition(navigationInTransition, this._newContentPresenter, newTransition);
			};
			this._readyToTransitionToNewContent = false;
			this._storedNavigationInTransition = null;
			this._storedNewTransition = null;
			TransitionFrame.PerformTransition(navigationInTransition, this._newContentPresenter, newTransition);
		}
		private static void EnsureStoppedTransition(ITransition transition)
		{
			if (transition != null && transition.GetCurrentState() != 2)
			{
				transition.Stop();
			}
		}
		private static void PerformTransition(NavigationTransition navigationTransition, ContentPresenter presenter, ITransition transition)
		{
			if (navigationTransition != null)
			{
				navigationTransition.OnBeginTransition();
			}
			if (presenter != null && presenter.get_Opacity() != 1.0)
			{
				presenter.set_Opacity(1.0);
			}
			if (transition != null)
			{
				transition.Begin();
			}
		}
		private static void CompleteTransition(NavigationTransition navigationTransition, ContentPresenter presenter, ITransition transition)
		{
			if (transition != null)
			{
				transition.Stop();
			}
			TransitionFrame.RestoreContentPresenterInteractivity(presenter);
			if (navigationTransition != null)
			{
				navigationTransition.OnEndTransition();
			}
		}
		private static void PrepareContentPresenterForCompositor(ContentPresenter presenter, bool applyBitmapCache = true)
		{
			if (presenter != null)
			{
				if (applyBitmapCache)
				{
					presenter.set_CacheMode(TransitionFrame.BitmapCacheMode);
				}
				presenter.set_IsHitTestVisible(false);
			}
		}
		private static void RestoreContentPresenterInteractivity(ContentPresenter presenter)
		{
			if (presenter != null)
			{
				presenter.set_CacheMode(null);
				if (presenter.get_Opacity() != 1.0)
				{
					presenter.set_Opacity(1.0);
				}
				presenter.set_IsHitTestVisible(true);
			}
		}
	}
}
